#include "Collision.h"
#include <cmath>

namespace Collision
{

void resolve(Entity* e, Level* l)
{
    e->tick();

    e->setX(e->getX() + e->getMotionX());
    resolveX(e,l);

    e->setY(e->getY() + e->getMotionY());
    resolveY(e,l);

    e->updateSprite();
}

void resolveX(Entity* e, Level* l)
{
    AABB aa = e->getAbsoluteBoundingBox();
    AABB bb;
    float correction = 0;
    float i = aa.left;

    if(e->getMotionX() > 0)
        i += aa.width;

    i = static_cast<int>(i);

    for(int j=aa.top; j<=ceilf(aa.top + aa.height); j++)
    {
        if(l->getTexture(i,j))
        {
            aa.intersects(AABB(i,j,1,1),bb);
            if(bb.width > correction)
                correction = bb.width;
        }
    }

    correction = std::copysign(correction, e->getMotionX());

    if(correction)
    {
        e->setMotionX(0);
        e->setX(aa.left - correction);
    }

}

void resolveY(Entity* e, Level* l)
{
    AABB aa = e->getAbsoluteBoundingBox();
    AABB bb;
    float correction = 0;
    float j = aa.top;

    if(e->getMotionY() > 0)
        j += aa.height;

    j = static_cast<int>(j);

    for(int i=aa.left; i<=ceilf(aa.left + aa.width); i++)
    {
        if(l->getTexture(i,j))
        {
            aa.intersects(AABB(i,j,1,1),bb);
            if(bb.height > correction)
                correction = bb.height;
        }
    }

    correction = std::copysign(correction, e->getMotionY());

    if(correction)
    {
        e->setMotionY(0);
        e->setY(aa.top - correction);
    }
}

}
